//------------------------------------------------------------------------------
// <copyright company="Telligent Systems">
//     Copyright (c) Telligent Systems Corporation.  All rights reserved.
// </copyright> 
//------------------------------------------------------------------------------

using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;

namespace CommunityServer.Components
{
	/// <summary>
	/// Summary description for VideoModule.
	/// </summary>
	public class VideoModule : ICSModule
	{
		public VideoModule()
		{
		}

		#region ICSModule Members

		public void Init(CSApplication csa, XmlNode node)
		{
			csa.PrePostUpdate += new CSPostEventHandler(csa_PrePostUpdate);
			csa.PreRenderPost += new CSPostEventHandler(csa_PreRenderPost);

            if(node != null)
            {
                XmlAttribute width = node.Attributes["width"];
                if(width != null)
                    _width = Int32.Parse(width.Value);

                XmlAttribute height = node.Attributes["height"];
                if(height != null)
                    _height = Int32.Parse(height.Value);
            }
		}

        private int _width = 300;
        private int _height = 225;

		#endregion

		private void csa_PrePostUpdate(IContent content, CSPostEventArgs e)
		{
			Post post = content as Post;

			if(post != null && e.State != ObjectState.Delete)
			{
				if(post.HasVideo)
				{
					TextToken token = new TextToken();
					token.Token = "Video";

					if(!Regex.IsMatch(post.FormattedBody, token.Pattern, RegexOptions.IgnoreCase))
						post.FormattedBody += "[Video]";
				}
			}
		}

		private void csa_PreRenderPost(IContent content, CSPostEventArgs e)
		{
			Post post = content as Post;

            if(post == null || !post.HasVideo)
                return;

			foreach(TextPart tp in e.TextParts)
			{
				if(tp.Name.ToLower() == "video")
				{
					string videoUI = CreateInlineVideoUI(post, e.Target);
					content.FormattedBody = tp.Replace(content.FormattedBody, videoUI);
				}
			}
		}

		private string CreateInlineVideoUI(Post post, PostTarget target)
		{
			CSContext context = CSContext.Current;

			int height = post.VideoHeight < 0 ? _height : post.VideoHeight;
			int width = post.VideoWidth < 0 ? _width : post.VideoWidth;

			string details = string.Format(ResourceManager.GetString("PostDisplay_VideoPost_Details"), Globals.HtmlEncode(post.VideoFileFormat), Globals.HtmlEncode(post.VideoDuration));
			string altRendering = string.Format("<a href=\"{0}\"><img src=\"{1}\" border = \"0\" width=\"{4}\" height=\"{5}\"></a><br /><a href = \"{0}\">{2}</a><br />{3}",post.VideoUrl,post.VideoImageUrl,ResourceManager.GetString("PostDisplay_VideoPost_AlternateText"),details,width,height);

			StringBuilder ui = new StringBuilder();
			ui.AppendFormat("<p align=\"center\" id=\"video_{0}\">", post.PostID);

			if(context.IsWebRequest && target == PostTarget.Web)
			{
				StringBuilder playerUI = new StringBuilder();

				switch (post.VideoFileFormat.ToUpper())
				{
					case "MOV":

						playerUI.Append("<object ");
						AddProperty(playerUI, "width", width.ToString());
						AddProperty(playerUI, "height", (height + 16).ToString());
						AddProperty(playerUI, "classid", "clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B");
						AddProperty(playerUI, "codebase", "http://www.apple.com/qtactivex/qtplugin.cab");
						playerUI.Append(">");

						AddParameter(playerUI, "src", post.VideoUrl);
						AddParameter(playerUI, "autoplay", "true");
						AddParameter(playerUI, "controller", "true");
						AddParameter(playerUI, "scale", "tofit");
						
						playerUI.Append("<embed ");
						AddProperty(playerUI, "width", width.ToString());
						AddProperty(playerUI, "height", (height + 16).ToString());
						AddProperty(playerUI, "src", post.VideoUrl);
						AddProperty(playerUI, "controller", "true");
						AddProperty(playerUI, "autoplay", "true");
						AddProperty(playerUI, "type", "video/quicktime");
						AddProperty(playerUI, "scale", "tofit");
						playerUI.Append(">");

						playerUI.Append("<noembed>");
						playerUI.Append(altRendering);
						playerUI.Append("</noembed>");

						playerUI.Append("</embed>");
						playerUI.Append("</object>");

						break;

					case "RA":
					case "RAM":
					case "RPM":
					case "RV":

						playerUI.Append("<object id=\"RVOCX\" ");
						AddProperty(playerUI, "width", width.ToString());
						AddProperty(playerUI, "height", height.ToString());
						AddProperty(playerUI, "classid", "clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA");
						playerUI.Append(">");

						AddParameter(playerUI, "src", post.VideoUrl);
						AddParameter(playerUI, "controls", "ImageWindow");
						AddParameter(playerUI, "console", "one");
						AddParameter(playerUI, "autostart", "true");
						
						playerUI.Append("<embed ");
						AddProperty(playerUI, "width", width.ToString());
						AddProperty(playerUI, "height", height.ToString());
						AddProperty(playerUI, "src", post.VideoUrl);
						AddProperty(playerUI, "console", "one");
						AddProperty(playerUI, "controls", "ImageWindow");

						AddProperty(playerUI, "autostart", "false");
						AddProperty(playerUI, "type", "audio/x-pn-realaudio-plugin");
						playerUI.Append(">");

						playerUI.Append("<noembed>");
						playerUI.Append(altRendering);
						playerUI.Append("</noembed>");

						playerUI.Append("</embed>");
						playerUI.Append("</object>");

						playerUI.Append("<br /><object id=\"RVOCX\" ");
						AddProperty(playerUI, "width", width.ToString());
						AddProperty(playerUI, "height", "32");
						AddProperty(playerUI, "classid", "clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA");
						playerUI.Append(">");

						AddParameter(playerUI, "src", post.VideoUrl);
						AddParameter(playerUI, "controls", "ControlPanel");
						AddParameter(playerUI, "autostart", "true");
						AddParameter(playerUI, "console", "one");
						
						playerUI.Append("<embed ");
						AddProperty(playerUI, "width", width.ToString());
						AddProperty(playerUI, "height", "32");
						AddProperty(playerUI, "src", post.VideoUrl);
						AddProperty(playerUI, "controls", "ControlPanel");
						AddProperty(playerUI, "autostart", "true");
						AddProperty(playerUI, "type", "audio/x-pn-realaudio-plugin");
						AddProperty(playerUI, "console", "one");
						playerUI.Append(">");

						playerUI.Append("</embed>");
						playerUI.Append("</object>");
						
						break;

					case "SWF":

						playerUI.Append("<object ");
						AddProperty(playerUI, "width", width.ToString());
						AddProperty(playerUI, "height", height.ToString());
						AddProperty(playerUI, "classid", "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000");
						AddProperty(playerUI, "codebase", "http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab");
						playerUI.Append(">");

						AddParameter(playerUI, "movie", post.VideoUrl);
						AddParameter(playerUI, "quality", "high");
						
						playerUI.Append("<embed ");
						AddProperty(playerUI, "width", width.ToString());
						AddProperty(playerUI, "height", height.ToString());
						AddProperty(playerUI, "src", post.VideoUrl);
						AddProperty(playerUI, "quality", "high");
						AddProperty(playerUI, "type", "application/x-shockwave-flash");
						AddProperty(playerUI, "pluginspage", "http://www.macromedia.com/go/getflashplayer");
						playerUI.Append(">");

						playerUI.Append("<noembed>");
						playerUI.Append(altRendering);
						playerUI.Append("</noembed>");

						playerUI.Append("</embed>");
						playerUI.Append("</object>");

						break;

					default:

						playerUI.Append("<object ");
						AddProperty(playerUI, "classid", "CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6");
						AddProperty(playerUI, "width", width.ToString());
						AddProperty(playerUI, "height", height.ToString());
						playerUI.Append(">");

						AddParameter(playerUI, "SendPlayStateChangeEvents", "True");
						AddParameter(playerUI, "AutoStart", "True");
						AddParameter(playerUI, "enabled", "True");
						AddParameter(playerUI, "uiMode", "full");
						AddParameter(playerUI, "PlayCount", "1");
						AddParameter(playerUI, "URL", post.VideoUrl);
						AddParameter(playerUI, "autoplay", "true");
						AddParameter(playerUI, "controller", "true");
						AddParameter(playerUI, "scale", "tofit");
						AddParameter(playerUI, "type", "application/x-oleobject");

						playerUI.Append("<embed ");
						AddProperty(playerUI, "width", width.ToString());
						AddProperty(playerUI, "height", height.ToString());
						AddProperty(playerUI, "showstatusbar", "0");
						AddProperty(playerUI, "showcontrols", "1");
						AddProperty(playerUI, "showdisplay", "0");
						AddProperty(playerUI, "autostart", "1");
						AddProperty(playerUI, "src", post.VideoUrl);
						AddProperty(playerUI, "controller", "true");
						AddProperty(playerUI, "autoplay", "true");
						AddProperty(playerUI, "scale", "tofit");
						AddProperty(playerUI, "type", DetermineType(post.VideoFileFormat.ToUpper()));
						playerUI.Append(">");

						playerUI.Append("<noembed>");
						playerUI.Append(altRendering);
						playerUI.Append("</noembed>");

						playerUI.Append("</embed>");
						playerUI.Append("</object>");

						break;
				}

				ui.AppendFormat("<span style=\"display: block; width: {0}px; height: {1}px; position: relative; margin-left: auto; margin-right: auto; border: solid 3px #000; overflow: hidden;\">", width, height);
				ui.AppendFormat("<img src=\"{0}\" width=\"{1}\" height=\"{2}\" />", post.VideoImageUrl, width, height);
				ui.AppendFormat("<a style=\"position: absolute; left: 0px; top: 0px; display: block; width: {0}px; height: {1}px; background: url({2}/utility/images/playoverlay.gif) no-repeat center center;\" href=\"{3}\" onclick=\"document.getElementById('video_{4}').innerHTML='{5}';return false;\">", width, height, Globals.ApplicationPath, post.VideoUrl, post.PostID, Globals.HtmlEncode(JavaScript.Encode(playerUI.ToString())));
				ui.AppendFormat("</a><span style=\"display: block; width: {0}px; position: absolute; left: 0px; top: {1}px; background-color: #000; color: #fff; padding: 6px; padding-left: 0px; padding-right: 0px; overflow: hidden; font-family: Arial, Helvetica; font-size: 8pt; font-weight: bold;\">{2}</span></span>", width, ((int) ((float) height) * .75), details);
			}
			else
			{
				ui.Append(altRendering);
			}

			ui.Append("</p>");
			return ui.ToString();
		}

		private void AddProperty(StringBuilder sb, string name, string value)
		{
			sb.Append(name);
			sb.Append("=\"");
			sb.Append(value);
			sb.Append("\" ");
		}

		private void AddParameter(StringBuilder sb, string name, string value)
		{
			sb.Append("<param name=\"");
			sb.Append(name);
			sb.Append("\" value=\"");
			sb.Append(value);
			sb.Append("\" />");
		}

		private string DetermineType(string ext)
		{
			switch (ext)
			{
				case "ASF":
				case "ASX":
				case "WVX":
				case "WM":
				case "WMX":
				case "WMV":
					return "video/x-ms-" + ext.ToLower();
				
				case "AVI":
					return "video/avi";

				case "MPG":
					return "video/mpeg";

				case "MP4":
					return "video/mpeg4";

				default:
					return "application/x-mplayer2";
			}
		}
	}
}
